package com.kaifamiao.jdbc.core;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DbUtil {

    private static final String PREFIX = "jdbc.connection.";
    private static final String SUFFIX_DRIVER = ".driver";
    private static final String SUFFIX_URL = ".url";
    private static final String SUFFIX_USER = ".user";
    private static final String SUFFIX_PASSWORD = ".password";
    private static final String CONNECT = "connect";
    private static final String DEFAULT_CONNECT = "mysql" ;

    private final Properties props = new Properties();

    private String driverClassName;
    private String url;
    private String user;
    private String password;

    private DbUtil(){
        super();
    }

    public static DbUtil getInstance() {
        return getInstance( "jdbc.properties" );
    }

    public static DbUtil getInstance( String filename ) {
        DbUtil du = new DbUtil();
        du.read( filename );
        du.parse();
        return du;
    }

    /**
     * 读取 类路径根目录下 指定文件 中的 "名-值" 对 到 props 集合
     * @param filename 被读取的文件名称
     * @throws IOException
     */
    private void read( String filename ) {
        // 获得当前实例(this)对应的类的 Class实例
        Class<?> c = this.getClass();
        // 获得用于读取 类路径根目录("/") 下 指定文件(filename) 的字节输入流
        InputStream in = c.getResourceAsStream( "/" + filename );
        try {
            // 从字节输入流中加载 "属性名-属性值" 对 到 Properties集合中
            props.load(in);
            // 关闭字节输入流
            in.close();
        } catch ( IOException e ) {
            System.out.println( "读取资源文件时发生错误: " + e.getMessage() );
        }
    }

    /**
     * 从 props 集合中读取相应的属性值并赋值给实例变量
     */
    private void parse(){
        String connect = props.getProperty( CONNECT , DEFAULT_CONNECT);
        connect = connect.isBlank() ? DEFAULT_CONNECT : connect;
        driverClassName = props.getProperty(  PREFIX+ connect + SUFFIX_DRIVER );
        url = props.getProperty( PREFIX + connect + SUFFIX_URL );
        user = props.getProperty( PREFIX + connect + SUFFIX_USER );
        password = props.getProperty( PREFIX + connect + SUFFIX_PASSWORD );
    }

    /**
     * 加载并注册驱动
     */
    public void load(){
        try {
            Class.forName( driverClassName );
        } catch (ClassNotFoundException e) {
            System.err.println( "驱动类" + driverClassName + "不存在" );
        }
    }

    /**
     * 建立数据库连接
     * @return
     */
    public Connection connect(){
        Connection conn = null ;

        try {
            conn = DriverManager.getConnection( url, user, password );
        } catch (SQLException e) {
            System.out.println( "数据库连接失败: " + e.getMessage() );
        }

        return conn;
    }

    /**
     * 根据指定的连接创建 Statement对象
     * @param conn
     * @return
     */
    public Statement create( Connection conn ){
        Statement stmt = null ;

        try {
            stmt = conn.createStatement();
        } catch (SQLException e) {
            System.out.println( "创建Statement失败:" + e.getMessage() );
        }

        return stmt;
    }

    /**
     * 释放资源
     * @param ac 即将被关闭的资源
     */
    public void release( AutoCloseable ac ){
        if( ac != null ) {
            try {
                ac.close();
            } catch (Exception e) {
                System.out.println( "释放资源时发生错误: " + e.getMessage() );
            }
        }
    }

}
